#include "gsoapserver.h"

//#include "../gSoapFoundation/soap.nsmap"
#include "gSoapFoundation/soapStub.h"

//using namespace hmigsoapnamespace;队列里面存储多个客户套接字的函数请求．
//*******************************************************
pthread_mutex_t queueCs;                //队列锁
pthread_cond_t queueCv;                 //条件变量
SOAP_SOCKET queue[MAX_QUEUE];           //数组队列
int head=0, tail=0;                     //队列头队列尾初始化

void *processQueue(void *);             //线程入口函数
int enqueue(SOAP_SOCKET);               //入队列函数
SOAP_SOCKET dequeue(void);              //出队列函数

//*******************************************************
GsoapServer::GsoapServer()
{
}

GsoapServer::~GsoapServer()
{
    soap_destroy(&currentSoapServer);
    soap_end(&currentSoapServer);
    soap_done(&currentSoapServer);
    free(&currentSoapServer);
}

bool GsoapServer::startServer(int port)
{
    std::cout << "startServer open1111111\n\n\n";
    //锁和条件变量初始化
    pthread_mutex_init(&queueCs,NULL);
    pthread_cond_init(&queueCv,NULL);
//    soap_init(&currentSoapServer);
    //recieveSoap.connect_timeout = 5;
//    recieveSoap.accept_timeout = 5;
    currentSoapServer.send_timeout = 1;//超时判定
    currentSoapServer.recv_timeout = 1;
    soap_set_mode(&currentSoapServer,SOAP_C_UTFSTRING);//UTF-8

//    std::cout << "bind===========";
    SOAP_SOCKET m = soap_bind(&currentSoapServer, NULL, port, BACKLOG);
//    std::cout << "启动失败=====m======"<<m<<"\n\n\n";
//    if(m < 0)//启动失败
//    {
//        return false;
//    }
    //循环直至服务套接字合法
    while (!soap_valid_socket(m))
    {
        fprintf(stderr,"gsoap Bind port error! ");
        m = soap_bind(&currentSoapServer, NULL, port, BACKLOG);
    }
    fprintf(stderr,"socket connection successful %d ",m);

    return true;
}
void GsoapServer::loopRecvServer_hualei()
{

    SOAP_SOCKET s;

    //生成服务线程
    for(int i = 0; i <MAX_THREAD; i++)
    {
        recieveSoapArry[i] = soap_copy(&currentSoapServer);
        fprintf(stderr,"Starting gsoap thread %d ",i);
        pthread_create(&tid[i],NULL,(void*(*)(void*))processQueue,(void*)recieveSoapArry[i]);
    }

    for(;;)
    {
        //接受客户端的连接,函数请求．
        s = soap_accept(&currentSoapServer);
        if (!soap_valid_socket(s))
        {
            if (currentSoapServer.errnum)
            {
                std::cout << "142888debugflag gsoap error\n\n\n如果一个rpc函数被卡住没有返回，会导致一直创建socket,但是不能正常工作";
                soap_print_fault(&currentSoapServer,stderr);
                continue;
            }
            else
            {
                fprintf(stderr,"gsoap Server timed out ");
                exit(-1);
                break;
            }
        }
        //客户端的IP地址
//        fprintf(stderr,"gsoap Accepted connection from IP= %d.%d.%d.%d socket = %d ",
//                ((currentSoapServer.ip)>>24)&&0xFF,((currentSoapServer.ip)>>16)&0xFF,((currentSoapServer.ip)>>8)&0xFF,(currentSoapServer.ip)&0xFF,(currentSoapServer.socket));
        //请求的套接字进入队列，如果队列已满则循环等待
        while(enqueue(s) == SOAP_EOM)
        {
            printf("gsoap  enqueue(s) == SOAP_EOM 请求的套接字进入队列，队列已满");
            sleep(1);
        }

    }
    //服务结束后的清理工作
    for(int i = 0; i < MAX_THREAD; i++)
    {
      while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
       {
           sleep(1);
      }
    }
    for(int i=0; i< MAX_THREAD; i++)
    {
      fprintf(stderr,"gsoap Waiting for thread %d to terminate ..",i);
      pthread_join(tid[i],NULL);
      fprintf(stderr,"gsoap terminated ");
      soap_done(recieveSoapArry[i]);
      free(recieveSoapArry[i]);
    }
    pthread_mutex_destroy(&queueCs);
    pthread_cond_destroy(&queueCv);

    //分离运行时的环境
     soap_done(&currentSoapServer);
}

void GsoapServer::loopRecvServer()
{
    //已在头文件初始化
    //struct soap *soapThread[MAX_THREAD];
    //pthread_t tid[MAX_THREAD];

    //锁和条件变量初始化
    pthread_mutex_init(&queueCs,NULL);
    pthread_cond_init(&queueCv,NULL);

//    //绑定服务端口 SOAP_SOCKET = int
//    SOAP_SOCKET m = soap_bind(&recieveSoap,"192.168.1.136",5050,BACKLOG);
//    //循环直至服务套接字合法
//    while (!soap_valid_socket(m))
//    {
//        fprintf(stderr,"Bind port error! ");
//        m = soap_bind(&recieveSoap,"192.168.1.136",5050,BACKLOG);
//    }
//    fprintf(stderr,"socket connection successful %d \n",m);

    //生成服务线程
    for(int i = 0;i<MAX_THREAD;i++)
    {
        recieveSoapArry[i] = soap_copy(&currentSoapServer);
        recieveSoapArry[i]->send_timeout = 2;
        recieveSoapArry[i]->recv_timeout = 2;
        pthread_create(&tid[i],NULL,(void*(*)(void*))processQueue,(void*)recieveSoapArry[i]);
//        //设置优先级
//        struct sched_param param;
//        param.__sched_priority = 20;
//        sched_setscheduler(tid[i],SCHED_OTHER,&param);
    }

    fprintf(stderr,"Starting gsoap threads !\n" );

    std::cout<<&currentSoapServer<<std::endl;
    do{
        SOAP_SOCKET s = soap_accept(&currentSoapServer);//等待连接
//        if(!soap_valid_socket(s))
//        {
//            std::cout<<"here3"<<std::endl;
//            if(recieveSoap.errnum)
//            {
//                soap_print_fault(&recieveSoap,stderr);
//                continue;
//            }
//            else
//            {
//                fprintf(stderr,"Server timed out \n");
//                break;
//            }

//            fprintf(stderr,"Accepted connection from IP= %d.%d.%d.%d socket = %d ",
//            ((recieveSoap.ip)>>24)&&0xFF,((recieveSoap.ip)>>16)&0xFF,((recieveSoap.ip)>>8)&0xFF,(recieveSoap.ip)&0xFF,(recieveSoap.socket));
//            //请求的套接字进入队列，如果队列已满则循环等待
//            while(enqueue(s) == SOAP_EOM)
//            sleep(1);
//        }

        if (s < 0)
        {
            soap_print_fault(&currentSoapServer, stderr);
            exit(-1);
        }
        printf("新gsoap client 客户ip地址：from %ld.%ld.%ld.%ld :\n",
               ((currentSoapServer.ip)>>24) & 0xFF,
               ((currentSoapServer.ip)>>16) & 0xFF,
               ((currentSoapServer.ip)>>8) & 0xFF,
               (currentSoapServer.ip) & 0xFF);
        while(enqueue(s) == SOAP_EOM)
        {
            printf("gsoap warn :enqueue(s) == SOAP_EOM 队列请求已经满了！\n");
            usleep(1000);
        }

//        soap_serve(&recieveSoap); //该句说明该server的服务
//        soap_end(&recieveSoap);

//        std::cout<<&recieveSoap<<std::endl;
    }while(1);
}

void GsoapServer::quitServer()
{
//    soap_force_closesock(&recieveSoap);
//    //服务结束后的清理工作
//    std::cout << "quit and clean gsoapServer"<<std::endl;

//    for(int i = 0; i < MAX_THREAD; i++)
//    {
//        while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
//        {
//            usleep(10);
//        }
//    }

//    fprintf(stderr,"Waiting for threads terminated!\n" );
//    for(int i=0; i< MAX_THREAD; i++)
//    {
//        pthread_join(tid[i],NULL);
//     //   fprintf(stderr,"terminated \n");

////        soap_destroy( recieveSoapThread[i] );
////        soap_end( recieveSoapThread[i] );
//        soap_done( recieveSoapArry[i]) ;
//        free( recieveSoapArry[i] );
//    }
//    pthread_mutex_destroy(&queueCs);
//    pthread_cond_destroy(&queueCv);


//    //soap_destroy(&recieveSoap);
//    //soap_end(&recieveSoap);
//    soap_done(&currentSoapServer);
//    //soap_free(&recieveSoap);//clean实例 2016.11.09存在问题

}

#include <unistd.h>
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)
//线程入口函数
void * processQueue(void *soap)
{
//    printf("************************gsoap this thread tid = %u\n", pthread_self());
    printf("************************gsoap this thread tid = %u\n", gettid());
    usleep(49000);
//    qDebug()<<"************************RosApi::threadRun pid="<<getpid();
    struct soap * tsoap = (struct soap *)soap;
    for(;;)
    {
        tsoap->socket = dequeue();
        if (!soap_valid_socket(tsoap->socket))
        {
            break;
        }
//        rosgsoapnamespace__serve(tsoap);
        soap_serve(tsoap);
//        soap_serve(tsoap);
        soap_destroy(tsoap);
        soap_end(tsoap);
        //fprintf(stderr,"served\n");
    }
    return NULL;
}

//new线程入口函数
//void * process_queue(void * soap)
//{
//  struct soap * tsoap = (struct soap *)soap;
//  for(;;)
//  {
//        tsoap->socket = dequeue();
//        if (!soap_valid_socket(tsoap->socket))
//       {
//         break;
//        }
//        soap_serve(tsoap);
//        soap_destroy(tsoap);
//        soap_end(tsoap);
//  }
//  return NULL;
//}

//入队列操作
//int enqueue(SOAP_SOCKET sock)
//{
//    int status = SOAP_OK;
//    int next;
//    pthread_mutex_lock(&queueCs);
//    next = tail +1;
//    if (next >= MAX_QUEUE)
//        next = 0;
//    if (next == head)
//        status = SOAP_EOM;
//    else
//    {
//        queue[tail] =sock;
//        tail = next;
//        pthread_cond_signal(&queueCv);
//    }
//    pthread_mutex_unlock(&queueCs);
//    return status;
//}

//new入队列操作
int enqueue(SOAP_SOCKET sock)
{
  int status = SOAP_OK;
  int next;
  pthread_mutex_lock(&queueCs);
  next = tail +1;
  if (next >= MAX_QUEUE)
    next = 0;
  if (next == head)
      status = SOAP_EOM;
  else
  {
    queue[tail] =sock;
    tail = next;
  }
  pthread_cond_signal(&queueCv);
  pthread_mutex_unlock(&queueCs);
  return status;
}

//出队列操作
//SOAP_SOCKET dequeue()
//{
//    SOAP_SOCKET sock;
//    pthread_mutex_lock(&queueCs);
////    while (head == tail )
////    {
////        pthread_cond_wait(&queueCv,&queueCs);
////    }

//    pthread_cond_wait(&queueCv,&queueCs);
//    sock = queue[head++];
//    if (head >= MAX_QUEUE)
//    {
//        head =0;
//    }
//    pthread_mutex_unlock(&queueCs);
//    return sock;
//}


//new出队列操作
SOAP_SOCKET dequeue()
{
  SOAP_SOCKET sock;
  pthread_mutex_lock(&queueCs);
   while (head == tail )
   {
          pthread_cond_wait(&queueCv,&queueCs);
   }
  sock = queue[head++];
  if (head >= MAX_QUEUE)
        {
    head =0;
  }
  pthread_mutex_unlock(&queueCs);
  return sock;
}

